package dominio;

import java.awt.Color;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.uqbar.commons.model.ObservableUtils;
import org.uqbar.commons.utils.Observable;

import exceptions.ErrorTerreno;
@Observable
public class Fila implements Serializable{

	private List<Casillero> casilleros;
	private boolean terrestre = true;

	public Fila(List<Casillero> cs) {
		this.casilleros = cs;
	}

	/**
	 * Crea una fila nueva
	 * @param len: cantidad de casilleros vacios
	 * @param terrestre: false si es acuatica
	 */
	public Fila(int len, boolean terrestre) {
		
		this.terrestre = terrestre;
		
		// Inicializar los casilleros
		this.casilleros = new ArrayList<Casillero>();
		
		for (int i = 0; i < len; i++) {
			this.casilleros.add(new Casillero(terrestre));
		}
	}

	/**
	 * Agrega una "planta" al casillero "index" si no esta ocupado
	 * y la planta corresponde al terreno
	 * (la verificacion la hace el casillero)
	 * @param index
	 * @param planta
	 * @throws ErrorTerreno, si la planta no es del mismo terreno de la fila
	 * @throws CasilleroOcupado, si estaba ocupado
	 */
	public void addPlanta(int index, Planta planta) {
		this.casilleros.get(index).plantar(planta);
	}

	/**
	 * @precond hay plantas en la fila
	 * @return primera planta en la fila, desde la derecha
	 */
	public Planta obtenerPrimeraPlantaAtacable() {
		Casillero atacable = obtenerCasilleroPrimeraPlantaAtacable();
		
		if(atacable != null) {
			return atacable.getPlanta();
		}
		return null;
	}

	/**
	 * @precond hay plantas en la fila
	 * Obtengo primer casillero mas proximo a ser atacado, para esto, antes
	 * invierto los casilleros Notar que se retorna una copia invertida.
	 * 
	 * @return
	 */
	public Casillero obtenerCasilleroPrimeraPlantaAtacable() {
		for (Casillero c : invertir(this.casilleros)) {
			if (c.ocupado()) {
				//ObservableUtils.forceFirePropertyChanged(c, "ocupante", c.getOcupante());
				return c;
			}
		}
		return null;
	}

	public void sacarPrimeraPlantaSiEstaMuerta() {
		
		Casillero cx = this.obtenerCasilleroPrimeraPlantaAtacable();
		
		if(cx.getPlanta().estaMuerta()) {
			cx.desplantar();			
		}
	}

	public int puntosAtaquePlantas() {
		int puntosAtaqueTotal = 0;
		for (Casillero c : this.casilleros) {
			if (c.ocupado()) {
				puntosAtaqueTotal = puntosAtaqueTotal
						+ c.getPlanta().getPuntosAtaque();
			}

		}
		return puntosAtaqueTotal;
	}

	public int plantasVivasNum() {
		int num = 0;
		for (Casillero c : this.casilleros) {
			if (c.ocupado()) {
				num++;
			}
		}
		return num;
	}
	
	/**
	 * Devuelve un arrayList con los casilleros correspondientes
	 * en orden invertido
	 * @param s
	 * @return ArrayList
	 */
	public List<Casillero> invertir(List<Casillero> s) {
		List<Casillero>list = new ArrayList<Casillero>(s);
		Collections.reverse(list);
		return list;

	}
	
	/**
	 * Reinicia la fila desplantando todas las plantas
	 */
	public void reiniciar() {
		for (Casillero casillero : this.getCasilleros()) {
			casillero.desplantar();
		}
	}

	/**
	 * Verifica que exista alguna planta en la fila, notar que la existencia de
	 * una planta implica que puede luchar.
	 */
	public boolean hayPlantas() {
		for (Casillero c : this.casilleros) {
			if (c.ocupado()) {
				return true;
			}
		}
		return false;
	}

	public boolean esTerrestre() {
		return this.terrestre;
	}

	public void cambiarTipo() {
		this.terrestre = ! this.terrestre;
		}

	public List<Casillero> getCasilleros() {
		return this.casilleros;
	}

	public void setCasilleros(List<Casillero> casilleros) {
		this.casilleros = casilleros;
	}
	
	public boolean getTerrestre() {
		return terrestre;
	}
	
	public void setTerrestre(boolean terrestre) {
		this.terrestre = terrestre;
	}
	
	public Color getColor() {
		return this.getTerrestre() ? Color.GREEN : Color.BLUE;
	}
}
